﻿using SuperMap.Data.Processing;
using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using SuperMap.Data;

namespace ArcMapCache2SupermapCache
{
    class ArcMapXMLReader
    {
        private XmlDocument m_xmlDoc;
       
        //SpatialReference
        private string m_WKT = "";

        public string WKT
        {
            get { return m_WKT; }
            set { m_WKT = value; }
        }
        private double m_XOrigin = 0.0;

        public double XOrigin
        {
            get { return m_XOrigin; }
            set { m_XOrigin = value; }
        }
        private double m_Yorigin = 0.0;

        public double Yorigin
        {
            get { return m_Yorigin; }
            set { m_Yorigin = value; }
        }
        private double m_XYScale = 0.0;
        private double m_ZOrigin = 0.0;
        private double m_ZScale = 0.0;
        private double m_MOrigin = 0.0;
        private double m_MScale = 0.0;
        private double m_XYTolerance = 0.0;
        private double m_ZTolerance = 0.0;
        private double m_MTolerance = 0.0;
        private double m_LeftLongitude = 0.0;
        private int m_WKID = 0;
        
        //生成瓦片的像素大小
        private int m_TileCols = 0;
        private int m_TileRows = 0;
        private double m_TileOriginX = 0.0;

        
        private double m_TileOriginY = 0.0;
        private double m_TileDPI = 0;

        private Rectangle2D m_CacheBounds = new Rectangle2D();

        public Rectangle2D CacheBounds
        {
            get { return m_CacheBounds; }
            set { m_CacheBounds = value; }
        }

        private TileFormat m_CacheTileFormat = TileFormat.PNG;

        public TileFormat CacheTileFormat
        {
            get { return m_CacheTileFormat; }
            set { m_CacheTileFormat = value; }
        }
        private int m_CompressionQuality = 0;

        public int CompressionQuality
        {
            get { return m_CompressionQuality; }
            set { m_CompressionQuality = value; }
        }

        //解析arcmap图片路径使用    
        //各级比例尺标题信息
        private Dictionary<String, Double> m_CacheCaptionsScales;

        private String m_filePath = "";

        public String FilePath
        {
            get { return m_filePath; }
            private set { }
        }

        public double TileDPI
        {
            get { return m_TileDPI; }
            set { m_TileDPI = value; }
        }

        public int TileCols
        {
            get { return m_TileCols; }
            set { m_TileCols = value; }
        }

        public double TileOriginY
        {
            get { return m_TileOriginY; }
            set { m_TileOriginY = value; }
        }

        public double TileOriginX
        {
            get { return m_TileOriginX; }
            set { m_TileOriginX = value; }
        }

        public int TileRows
        {
            get { return m_TileRows; }
            set { m_TileRows = value; }
        }

        public Dictionary<String, Double> CaptionCacheScales
        {
            get { return m_CacheCaptionsScales; }
        }

        public double MOrigin
        {
            get { return m_MOrigin; }
            set { m_MOrigin = value; }
        }

        public ArcMapXMLReader()
        {
            m_xmlDoc = new XmlDocument();
            m_CacheCaptionsScales = new Dictionary<String, Double>();
            m_WKT = String.Empty;

        }

        public Boolean Open(string configPath)
        {
            if (!File.Exists(configPath))
            {
                return false;
            }

            m_filePath = configPath;
            return FromConfigFile(configPath);
        }


        private Boolean FromConfigFile(string configPath)
        {
            m_xmlDoc.Load(configPath);

            XmlNode rootNode = m_xmlDoc.SelectSingleNode("CacheInfo");
            AnalyzeXMLNode(rootNode);

            string configDir = Path.GetDirectoryName(m_filePath);
            

            string confFile = configDir + "\\conf.cdi";

            if (File.Exists(confFile))
            {
                XmlDocument cdiReader = new XmlDocument();
                cdiReader.Load(confFile);
                XmlNode envelopeNNode = cdiReader.SelectSingleNode("EnvelopeN");

                Rectangle2D retangle2D = new Rectangle2D();
                foreach (XmlNode boundsNode in envelopeNNode.ChildNodes)
                {
                    if (boundsNode.Name == "XMin")
                    {
                        retangle2D.Left = Double.Parse(boundsNode.InnerText);  
                    }
                    else if (boundsNode.Name == "YMin")
                    {
                        retangle2D.Bottom = Double.Parse(boundsNode.InnerText);  
                    }
                    else if (boundsNode.Name == "XMax")
                    {
                        retangle2D.Right = Double.Parse(boundsNode.InnerText);  
                    }
                    else if (boundsNode.Name == "YMax")
                    {
                        retangle2D.Top = Double.Parse(boundsNode.InnerText);  
                    }
                }

                m_CacheBounds = retangle2D;


            }
            else
            {

            }

            return true;
        }

        private void AnalyzeXMLNode(XmlNode xmlNode)
        {
            if (xmlNode == null)
            {
                return;
            }

            //进入解析时，先分析属性块
            if (xmlNode.Name == "LODInfo")
            {
                string dCaption = "";
                double dscale = 0;

                foreach (XmlNode child in xmlNode.ChildNodes)
                {
                    if (child.Name == "Scale")
                    {
                        dscale = 1/(Double.Parse(child.InnerText)*(1001122.8/1000000));
                    }
                    else if (child.Name == "LevelID")
                    {
                        dCaption = child.InnerText;

                        if (dCaption.Length == 1)
                        {
                            dCaption = "L0" + dCaption;
                        }
                        else
                        {
                            dCaption = "L" + dCaption;
                        }
                    }
                }

                m_CacheCaptionsScales.Add(dCaption, dscale);
            }

            if (xmlNode.Name == "TileOrigin")
            {
                foreach (XmlNode child in xmlNode.ChildNodes)
                {
                    if (child.Name == "X")
                    {
                        m_TileOriginX = Double.Parse(child.InnerText);
                    }
                    else if (child.Name == "Y")
                    {
                        m_TileOriginY = Double.Parse(child.InnerText);
                    }
                }

            }


            if (xmlNode.ChildNodes.Count == 1)
            {
                switch (xmlNode.Name)
                {
                    case "WKT": 
                        m_WKT = xmlNode.InnerText;
                        break;
                    case "XOrigin": 
                        m_XOrigin = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "YOrigin": 
                        m_Yorigin = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "ZOrigin": 
                        m_ZOrigin = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "ZScale":
                        m_ZScale = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "MOrigin": 
                        m_MOrigin = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "MScale": 
                        m_MScale = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "XYTolerance": 
                        m_XYTolerance = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "ZTolerance": 
                        m_ZTolerance = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "MTolerance": 
                        m_MTolerance = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "LeftLongitude": 
                        m_LeftLongitude = Double.Parse(xmlNode.InnerText); 
                        break;
                    case "WKID": 
                        m_WKID = int.Parse(xmlNode.InnerText); 
                        break;
                    case "TileCols" :
                        m_TileCols = int.Parse(xmlNode.InnerText);
                        break;
                    case "TileRows":
                        m_TileRows = int.Parse(xmlNode.InnerText);
                        break;
                    case "CacheTileFormat":

                        if (xmlNode.InnerText.Substring(0,3).Equals("png",StringComparison.OrdinalIgnoreCase))
                        {
                            m_CacheTileFormat = TileFormat.PNG;
                        }
                        else if(xmlNode.InnerText.Equals("jpeg",StringComparison.OrdinalIgnoreCase))
                        {
                            m_CacheTileFormat = TileFormat.JPG;
                        }
                        else if (xmlNode.InnerText.Equals("mixed", StringComparison.OrdinalIgnoreCase))
                        {
                            m_CacheTileFormat = TileFormat.JPG_PNG;
                        }
                        else
                        {

                        }
                       
                        break;
                    case "CompressionQuality":
                        m_CompressionQuality = int.Parse(xmlNode.InnerText);
                        break;
                    case "DPI":
                        m_TileDPI = Double.Parse(xmlNode.InnerText);
                        break;
                }


            }
            else
            {
                foreach (XmlNode childNode in xmlNode.ChildNodes)
                {
                    AnalyzeXMLNode(childNode);
                }  
            }
        }

//         public string GetTilePath(Double scale, Int32 row, Int32 col)
//         {
//             string tilePath = Path.GetFileName(m_filePath);
// 
// 
// 
// 
//         }

    }
}
